﻿Public Class FuncForm

    Private _Func As Core.Functions.MetisFunction

    Public Event ErrorOccurred(ByVal Message As String)

    Sub New(ByVal Func As Core.Functions.MetisFunction)
        InitializeComponent()
        _Func = Func

    End Sub

    Private Sub FuncForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        scFieldDef.Panel2Collapsed = (Not TypeOf _Func Is Core.Functions.MetisResultFunction)
        btnOpSets.Visible = (TypeOf _Func Is Core.Functions.MetisResultFunction)
        colExpr.Visible = (TypeOf _Func Is Core.Functions.MetisResultFunction)

        lblAction.Visible = (TypeOf _Func Is Core.Functions.MetisTableFunction)
        cmbAction.Visible = (TypeOf _Func Is Core.Functions.MetisTableFunction)
        btnExecute.Visible = (TypeOf _Func Is Core.Functions.MetisTableFunction)

        btnField_Add.Visible = (Not TypeOf _Func Is Core.Functions.MetisInternalFunction)
        btnField_Del.Visible = (Not TypeOf _Func Is Core.Functions.MetisInternalFunction)
        ToolStripSeparator3.Visible = (Not TypeOf _Func Is Core.Functions.MetisInternalFunction)

        btnMapTable.Visible = (TypeOf _Func Is Core.Functions.MetisInternalFunction)

        If _Func.LoadState = Core.MetisLoadState.NewDefinition Then
            tcMain.SelectTab(tpFieldDef)
            btnReload.Enabled = False
            btnExecute.Enabled = False
        Else
            ReloadData()
        End If
        dgvFieldDef.AutoGenerateColumns = False
        ReloadDefinition()
    End Sub

    Private Sub SetParentFieldList()
        Dim ParentFieldLUlist As New Components.DGVColumns.LookUpList
        ParentFieldLUlist.Add(New Core.MetisLookupListItem(-1, "", ""))
        For Each item As Core.Functions.MetisFunctionField In _Func.Fields
            If item.Dimension IsNot Nothing Then ParentFieldLUlist.Add(item)
        Next
        colParent.LookupList = ParentFieldLUlist
    End Sub

    Public ReadOnly Property [Function]() As Core.Functions.MetisFunction
        Get
            Return _Func
        End Get
    End Property

    Private Sub FormatInternalFuncField(ByVal row As DataGridViewRow)
        Dim tmpField As Core.Functions.MetisFunctionField = row.DataBoundItem

        row.Cells(colPK.Index).ReadOnly = True
        row.Cells(colPK.Index).Style.BackColor = SystemColors.Control
        row.Cells(colFieldDefault.Index).ReadOnly = True
        row.Cells(colFieldDefault.Index).Style.BackColor = SystemColors.Control
        row.Cells(colDim.Index).ReadOnly = True
        row.Cells(colDim.Index).Style.BackColor = SystemColors.Control
        row.Cells(colParent.Index).ReadOnly = True
        row.Cells(colParent.Index).Style.BackColor = SystemColors.Control

        row.Cells(colDBFieldName.Index).ReadOnly = True
        row.Cells(colDBFieldName.Index).Style.BackColor = SystemColors.Control
        row.Cells(colDBFieldType.Index).ReadOnly = True
        row.Cells(colDBFieldType.Index).Style.BackColor = SystemColors.Control
        row.Cells(colFieldDefault.Index).ReadOnly = True
        row.Cells(colFieldDefault.Index).Style.BackColor = SystemColors.Control
        row.Cells(colFieldLength.Index).ReadOnly = True
        row.Cells(colFieldLength.Index).Style.BackColor = SystemColors.Control
        row.Cells(colFieldNullable.Index).ReadOnly = True
        row.Cells(colFieldNullable.Index).Style.BackColor = SystemColors.Control

    End Sub

    Private Sub FormatTableFuncField(ByVal row As DataGridViewRow)
        Dim tmpField As Core.Functions.MetisFunctionField = row.DataBoundItem

        If tmpField.PK Then
            row.Cells(colFieldNullable.Index).ReadOnly = True
            row.Cells(colFieldNullable.Index).Style.BackColor = SystemColors.Control
        End If

        If tmpField.Dimension IsNot Nothing Or tmpField.ParentField IsNot Nothing Then
            row.Cells(colDBFieldType.Index).ReadOnly = True
            row.Cells(colDBFieldType.Index).Style.BackColor = SystemColors.Control
            row.Cells(colFieldLength.Index).ReadOnly = True
            row.Cells(colFieldLength.Index).Style.BackColor = SystemColors.Control
        End If

        If tmpField.ParentField IsNot Nothing Then
            row.Cells(colDim.Index).ReadOnly = True
            row.Cells(colDim.Index).Style.BackColor = SystemColors.Control
        End If
    End Sub

    Private Sub FormatFieldDefDGV()
        Try
            dgvFieldDef.SuspendLayout()
            For Each row As DataGridViewRow In dgvFieldDef.Rows
                Dim tmpField As Core.Functions.MetisFunctionField = row.DataBoundItem

                If tmpField.PK Then
                    row.DefaultCellStyle.Font = New Font(dgvFieldDef.DefaultCellStyle.Font, FontStyle.Bold)
                Else
                    row.DefaultCellStyle.Font = New Font(dgvFieldDef.DefaultCellStyle.Font, FontStyle.Regular)
                End If

                For Each cell As DataGridViewCell In row.Cells
                    cell.ReadOnly = False
                    cell.Style.BackColor = SystemColors.Window
                    cell.ToolTipText = ""
                Next
                If TypeOf _Func Is Core.Functions.MetisInternalFunction Then
                    FormatInternalFuncField(row)
                ElseIf TypeOf _Func Is Core.Functions.MetisInputFunction Then
                ElseIf TypeOf _Func Is Core.Functions.MetisViewFunction Then
                ElseIf TypeOf _Func Is Core.Functions.MetisTableFunction Then
                    FormatTableFuncField(row)
                End If

            Next
        Finally
            dgvFieldDef.ResumeLayout()
        End Try

    End Sub

    Private Function IsValidDefinition() As Boolean
        Dim tmpResult As Boolean = Core.MetisCore.IsValidFieldName(txtFuncName.Text, 64)
        Return tmpResult
    End Function

    Private Sub ReloadDefinition()
        _Func.Reload()
        Me.Text = _Func.Name
        txtFuncName.Text = _Func.Name
        txtTableName.Text = _Func.Table.TableName
        txtComment.Text = _Func.Annotation

        dgvFieldDef.DataSource = _Func.Fields

        If TypeOf _Func Is Core.Functions.MetisResultFunction Then
            Dim tmpFunc As Core.Functions.MetisResultFunction = _Func
            jdJoins.Init(tmpFunc)
            txtWhere.Text = tmpFunc.Where
            txtHaving.Text = tmpFunc.Having
            If TypeOf _Func Is Core.Functions.MetisTableFunction Then
                cmbAction.SelectedIndex = DirectCast(tmpFunc, Core.Functions.MetisTableFunction).Action
            End If
        End If

        SetParentFieldList()

        Dim DimLUlist As New Components.DGVColumns.LookUpList
        DimLUlist.Add(New Core.MetisLookupListItem(-1, "", ""))
        For Each item As Core.Dimensions.MetisDimension In _Func.MetisCore.Dimensions
            DimLUlist.Add(item)
        Next
        colDim.LookupList = DimLUlist

    End Sub

    Private Sub ReloadData()

    End Sub

    Private Sub dgvFieldDef_DataBindingComplete(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles dgvFieldDef.DataBindingComplete
        FormatFieldDefDGV()
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub txtFuncName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFuncName.TextChanged
        Try
            _Func.Name = txtFuncName.Text
            txtFuncName.BackColor = SystemColors.Window
            txtFuncName.ToolTipText = ""
            btnSave.Enabled = _Func.IsModified
        Catch ex As Core.Exceptions.MetisNameException
            txtFuncName.BackColor = Color.Salmon
            txtFuncName.ToolTipText = ex.Message
            btnSave.Enabled = False
        End Try
    End Sub

    Private Sub dgvFieldDef_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvFieldDef.CellEndEdit
        tsFieldDef.Enabled = True
        FormatFieldDefDGV()
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub btnField_Add_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnField_Add.Click
        _Func.Fields.Add(New Core.Functions.MetisFunctionField(_Func))
        'dgvFieldDef.DataSource = _Dim.Fields
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub btnField_Del_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnField_Del.Click
        _Func.Fields.Remove(dgvFieldDef.CurrentRow.DataBoundItem)
        'dgvFieldDef.DataSource = _Dim.Fields
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub txtComment_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtComment.TextChanged
        _Func.Annotation = txtComment.Text
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub dgvFieldDef_RowEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvFieldDef.RowEnter
        Dim tmpField As Core.Functions.MetisFunctionField = dgvFieldDef.Rows(e.RowIndex).DataBoundItem
        btnField_Del.Enabled = (tmpField.FieldType = Core.Functions.MetisFunctionFieldType.ValueField)
    End Sub

    Private Sub dgvFieldDef_DataError(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles dgvFieldDef.DataError
        If (e.ColumnIndex = colFieldName.Index) Or (e.ColumnIndex = colDBFieldName.Index) Or (e.ColumnIndex = colFieldLength.Index) Then
            If e.Exception IsNot Nothing Then RaiseEvent ErrorOccurred(e.Exception.Message)
            e.Cancel = True
        End If
    End Sub

    Private Sub dgvFieldDef_CellBeginEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles dgvFieldDef.CellBeginEdit
        tsFieldDef.Enabled = False
    End Sub

    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        _Func.Save()
        Me.Text = _Func.Name
        btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
    End Sub

    Private Sub btnReload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReload.Click
        ReloadDefinition()
    End Sub

    Private Sub DimForm_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If _Func.IsModified Then
            Select Case MsgBox(String.Format(My.Resources.FormCloseMsg_Dim.ToString, Me.Text), MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Question)
                Case MsgBoxResult.Yes
                    _Func.Save()
                    _Func.SaveFormat()
                Case MsgBoxResult.Cancel
                    e.Cancel = True
            End Select
        Else
            If _Func.LoadState <> Core.MetisLoadState.NewDefinition Then _Func.SaveFormat()
        End If

    End Sub

    Private Sub mnuJoinEdit_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles mnuJoinEdit.Opening
        miSetInnerJoin.Checked = (jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.InnerJoin)
        miSetLeftJoin.Checked = (jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.LeftJoin)
        miSetRightJoin.Checked = (jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.RightJoin)
    End Sub

    Private Sub miRemoveJoin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miRemoveJoin.Click
        Dim tmpFunc As Core.Functions.MetisResultFunction = _Func
        tmpFunc.Joins.Remove(jdJoins.SelectedJoin)
    End Sub

    Private Sub miSetLeftJoin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miSetLeftJoin.Click
        jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.LeftJoin
    End Sub

    Private Sub miSetInnerJoin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miSetInnerJoin.Click
        jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.InnerJoin
    End Sub

    Private Sub miSetRightJoin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miSetRightJoin.Click
        jdJoins.SelectedJoin.JoinType = Core.Functions.MetisJoinType.RightJoin
    End Sub

    Private Sub miRemoveTable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miRemoveTable.Click
        Dim tmpFunc As Core.Functions.MetisResultFunction = _Func
        tmpFunc.FunctionReferences.Remove(jdJoins.SelectedTable)
    End Sub

    Private Sub txtRefTableAlias_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtRefTableAlias.KeyUp
        If e.KeyData = Keys.Enter Then
            Try
                Dim tmpFunc As Core.Functions.MetisResultFunction = _Func

                jdJoins.SelectedTable.Alias = txtRefTableAlias.Text
                txtRefTableAlias.BackColor = SystemColors.Window
                txtRefTableAlias.ToolTipText = ""
                mnuJoinTableEdit.Close()
                'btnSave.Enabled = jdJoins.SelectedTable.IsModified
            Catch ex As Core.Exceptions.MetisNameException
                txtRefTableAlias.BackColor = Color.Salmon
                txtRefTableAlias.ToolTipText = ex.Message
                btnSave.Enabled = False
            End Try
        End If

    End Sub

    Private Sub miResetTableAlias_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles miResetTableAlias.Click
        jdJoins.SelectedTable.Alias = jdJoins.SelectedTable.CreateDefaultAlias
    End Sub

    Private Sub mnuJoinTableEdit_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles mnuJoinTableEdit.Opening
        txtRefTableAlias.Text = jdJoins.SelectedTable.Alias
        txtRefTableAlias.BackColor = SystemColors.Window
        txtRefTableAlias.ToolTipText = ""
    End Sub

    Private Sub jdJoins_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles jdJoins.DragOver
        If e.Data.GetDataPresent(GetType(Core.Functions.MetisInputFunction)) OrElse _
           e.Data.GetDataPresent(GetType(Core.Functions.MetisInternalFunction)) OrElse _
           e.Data.GetDataPresent(GetType(Core.Functions.MetisTableFunction)) OrElse _
           e.Data.GetDataPresent(GetType(Core.Functions.MetisViewFunction)) Then

            Dim SrcFunc As Core.Functions.MetisFunction
            If e.Data.GetDataPresent(GetType(Core.Functions.MetisInputFunction)) Then
                SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisInputFunction))
            ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisInternalFunction)) Then
                SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisInternalFunction))
            ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisTableFunction)) Then
                SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisTableFunction))
            ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisViewFunction)) Then
                SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisViewFunction))
            End If

            If (SrcFunc.Equals(_Func)) Then
                e.Effect = DragDropEffects.None
            Else
                e.Effect = DragDropEffects.Move
            End If

        End If
    End Sub

    Private Sub jdJoins_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles jdJoins.DragDrop
        Dim SrcFunc As Core.Functions.MetisFunction
        Dim tmpPoint As Drawing.Point = jdJoins.PointToClient(New Drawing.Point(e.X, e.Y))

        If e.Data.GetDataPresent(GetType(Core.Functions.MetisInputFunction)) Then
            SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisInputFunction))
        ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisInternalFunction)) Then
            SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisInternalFunction))
        ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisTableFunction)) Then
            SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisTableFunction))
        ElseIf e.Data.GetDataPresent(GetType(Core.Functions.MetisViewFunction)) Then
            SrcFunc = e.Data.GetData(GetType(Core.Functions.MetisViewFunction))
        End If
        DirectCast(_Func, Core.Functions.MetisResultFunction).FunctionReferences.Add(New Core.Functions.MetisRefFunction(_Func.MetisCore, _Func, SrcFunc, tmpPoint))
    End Sub


    Private Sub btnMapTable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMapTable.Click
        Dim frmSelDBTbl As New MapTableSelectForm
        frmSelDBTbl.InternalFunction = _Func
        If frmSelDBTbl.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
            _Func.Table = frmSelDBTbl.SelectedTable
            txtTableName.Text = _Func.Table.TableName
        End If

    End Sub

    Private Sub dgvFieldDef_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgvFieldDef.DragDrop
        If e.Data.GetDataPresent(GetType(Components.JoinDesigner.JoinDragDropStruct)) Then

            Dim tmpStruct As Components.JoinDesigner.JoinDragDropStruct
            tmpStruct = DirectCast(e.Data.GetData(GetType(Components.JoinDesigner.JoinDragDropStruct)), Components.JoinDesigner.JoinDragDropStruct)

            Dim tmpField As New Core.Functions.MetisFunctionField(_Func)

            tmpField.Name = tmpField.CreateFieldName(tmpStruct.FuncField.Name)
            tmpField.Dimension = tmpStruct.FuncField.Dimension
            tmpField.DBfieldType = tmpStruct.FuncField.DBfieldType
            tmpField.DBfieldLength = tmpStruct.FuncField.DBfieldLength
            tmpField.DBFieldName = tmpField.CreateDBFieldName(tmpStruct.FuncField.DBFieldName)
            tmpField.NumberFormat = tmpStruct.FuncField.NumberFormat
            tmpField.Expression = tmpStruct.FuncRef.Alias & "." & tmpStruct.FuncField.Name
            _Func.Fields.Add(tmpField)

            btnSave.Enabled = _Func.IsModified AndAlso IsValidDefinition()
        End If
    End Sub

    Private Sub dgvFieldDef_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles dgvFieldDef.DragOver
        If e.Data.GetDataPresent(GetType(Components.JoinDesigner.JoinDragDropStruct)) Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
End Class